// mesIntegration.js
import {plcEvents, writeToPLC} from '@/services/plc_service'
import {getConfig} from '@/mapper/config-store'
import {getLastUser} from '@/api/user'
import {getPlcInfo} from '@/api/plc'
import {mesLogger} from '@/mapper/mes-log-mapper'

let eventConfig = {}
let plcConfig = {}
let opid = null

const axios = require('axios')

async function loadConfig() {
    eventConfig = await getConfig('mesEventConfig')
    plcConfig = await getPlcInfo()
    opid = await getLastUser()
}

export async function startMesEventListen() {
    await loadConfig()
    plcEvents.on('value-changed', async (eventData) => {
        try {
            const {key, value, values, addresses} = eventData
            if (value === 0) {
                return
            }
            switch (key) {
                case 'station1_scanUpload'://工位1扫码信号
                    await processStationScan(values, addresses, "1")
                    break
                case 'station2_scanUpload'://工位2扫码信号
                    await processStationScan(values, addresses, "2")
                    break
                case 'station1_processComplete'://工位1生产完成信号
                    await processStationProcessComplete(values, addresses, "1")
                    break
                case 'station2_processComplete'://工位2生产完成信号
                    await processStationProcessComplete(values, addresses, "2")
                    break
            }
        } catch (e) {
            console.log('value-changed 报错:', e.message)
        }
    })

    plcEvents.on('device-status', async (eventData) => {
        try {
            let isConnection = eventData.isConnection
            await processDeviceStatus(isConnection)
        } catch (e) {
            console.log('device-status 报错:', e.message)
        }
    })
}

export async function stopPlcEventListen() {
    plcEvents.removeAllListeners('value-changed')
    console.log('PLC事件监听已停止。')
}

async function processDeviceStatus(isConnection) {
    let eventData = eventConfig.Status
    if (!eventData) {
        console.log('Status事件未配置')
        return
    }
    eventData.Line = plcConfig.lineId
    eventData.StationID = plcConfig.stationId
    eventData.MachineID = plcConfig.machineId
    eventData.OPID = "1"
    eventData.SendTime = currTime()
    eventData.STATUS = isConnection ? '1' : '2'
    let mesResult = await sendMesEvent(eventData)
    console.log('MES响应:', mesResult)
}


async function processStationScan(values, addresses, opid) {
    const SN = values[`station${opid}_scanData`]
    let eventData = eventConfig.SN_CheckIn
    if (!eventData) {
        console.log('SN_CheckIn事件未配置')
        return
    }
    eventData.Line = plcConfig.lineId
    eventData.StationID = plcConfig.stationId
    eventData.MachineID = plcConfig.machineId
    eventData.OPID = opid
    eventData.SendTime = currTime()
    eventData.SN = SN
    let mesResult = await sendMesEvent(eventData)
    console.log('MES响应:', mesResult)
    const {Result, MSG} = mesResult
    //扫码信号地址
    const scanUploadAddress = findAddress(addresses, `station${opid}_scanUpload`)
    await writeToPLC(scanUploadAddress, 0)
    //扫码结果地址
    const mesJudgmentAddress = findAddress(addresses, `station${opid}_mesJudgment`)
    if (Result === 'PASS') {
        await writeToPLC(mesJudgmentAddress, 1)
    } else {
        await writeToPLC(mesJudgmentAddress, 2)
        console.log('扫码失败:', MSG)
    }
    console.log(`工位${opid}扫码流程处理完毕`)
}

function findAddress(addresses, key) {
    let find = addresses.find(address => address.key === key);
    return find.address
}


async function processStationProcessComplete(values, addresses, opid) {
    const SN = values[`station${opid}_scanData`]
    let eventData = eventConfig.SN_CheckOut  // 修正为 SN_CheckOut 事件
    if (!eventData) {
        console.log('SN_CheckOut事件未配置')
        return
    }
    eventData.Line = plcConfig.lineId
    eventData.StationID = plcConfig.stationId
    eventData.MachineID = plcConfig.machineId
    eventData.OPID = opid
    eventData.SendTime = currTime()
    eventData.SN = SN
    eventData.DC_Info = buildDcInfo(opid, values, addresses)

    // 获取生产结果
    const processResult = values[`station${opid}_processResult`]
    eventData.Result = processResult === 1 ? 'PASS' : 'FAIL'
    // 发送MES事件
    let mesResult = await sendMesEvent(eventData)
    // 处理完成信号地址
    const processCompleteAddress = findAddress(addresses, `station${opid}_processComplete`)
    await writeToPLC(processCompleteAddress, 0)

    console.log(`工位${opid}生产完成流程处理完毕`, mesResult)
}

function buildDcInfo(opid, values, addresses) {
    let dcAddressList = addresses.filter((address) => {
        if (!address.station) {
            return false
        }
        return address.station === `station${opid}`
    });
    if (!dcAddressList || dcAddressList.length === 0) {
        return []
    }
    let result_list = []
    dcAddressList.forEach((address) => {
        let key = address.key
        result_list.push({
            Item: address.propertyName,
            Value: values[key]
        })
    })
    return result_list
}

async function sendMesEvent(orgData) {
    const eventData = JSON.parse(JSON.stringify(orgData));
    try {
        let url = eventData.url

        delete eventData.enabled
        delete eventData.url
        delete eventData.heartbeat_interval

        const EventID = eventData.EventID

        // console.log('发送数据:', eventData)
        const response = await axios.post(url, eventData)
        // 记录到数据库
        mesLogger.logMesInteraction(
            EventID,
            response.data.Result,
            response.data.MSG || '',
            eventData,
            response.data
        );
        return response.data
    } catch (error) {
        console.error('MES请求失败:', error)
        // 记录错误到数据库
        mesLogger.logMesInteraction(
            eventData.EventID,
            'FAIL',
            `请求失败: ${error.message}`,
            eventData,
            {error: error.message}
        );
    }
    return {
        Result: 'FAIL',
        MSG: `请求失败`
    }
}

function currTime() {
    //2025/02/08 08:32:05
    const now = new Date()
    return now.getFullYear() + '/' + String(now.getMonth() + 1).padStart(2, '0') + '/' + String(now.getDate()).padStart(2, '0') + ' ' + String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0') + ':' + String(now.getSeconds()).padStart(2, '0')
}
